﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TalkBot
{
    class Repository
    {

        public Repository()
        {
            m_isReading = false;
            m_hasCountedWords = false;
            m_isVocabularyInitialized = false;
            m_currentCategory = VocabularyCategory.VocabularyCategory_Count;
            m_keyword = Keyword.Keyword_NotFound;
            m_lastKeyword = m_keyword;
        }

        public enum VocabularyCategory 
        {
            VocabularyCategory_Rude,
            VocabularyCategory_Kind,
            VocabularyCategory_Awkward,
            VocabularyCategory_Count
        }

        public enum Keyword
        {
            Keyword_Category,
            Keyword_BeginWords,
            Keyword_EndWords,
            Keyword_NotFound
        }

        public void Initilize(string filename)
        {
            //Open file
            if (!System.IO.File.Exists(filename))
            {
                System.IO.File.Create(filename);
            }

            m_streamReader = new System.IO.StreamReader(filename);

            m_categoryCurrentIndexes = new Dictionary<VocabularyCategory,int>();
            m_Vocabulary = new Dictionary<VocabularyCategory, List<String>>();
            m_categoryWordCounts = new Dictionary<VocabularyCategory, int>();

            for (VocabularyCategory category = (VocabularyCategory)0; category < VocabularyCategory.VocabularyCategory_Count; category++)
            {
                m_categoryWordCounts.Add(category, 0);
                m_categoryCurrentIndexes.Add(category, 0);
                m_Vocabulary.Add(category, new List<String>());
            }

            //for (VocabularyCategory category = (VocabularyCategory)0; category < VocabularyCategory.VocabularyCategory_Count; category++)
            //{
            //    m_Vocabulary[category] = new List<String>();
            //}

            while (!m_streamReader.EndOfStream)
            {
                //Handle keywords in the input file
                string currentLine = m_streamReader.ReadLine();
                m_keyword = GetKeywordByString(currentLine);
                if ((m_keyword) != m_lastKeyword)
                {
                    HandleKeyword(m_keyword);
                }
                else if(m_isReading)
                {
                    if (!m_hasCountedWords)
                    {
                        m_categoryWordCounts[m_currentCategory]++;
                    }
                    else
                    {                     
                        m_Vocabulary[m_currentCategory].Add(currentLine);
                        m_categoryCurrentIndexes[m_currentCategory]++;
                    }
                }

                if (!m_hasCountedWords && m_streamReader.EndOfStream)
                {
                    m_streamReader.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);
                    m_hasCountedWords = true;
                }
                m_lastKeyword = m_keyword;
            }

        }

        public List<String> GetVocabularyByCategory(VocabularyCategory category)
        {
            if(category>=0 && category<VocabularyCategory.VocabularyCategory_Count)
            return m_Vocabulary[category];
            else
            return null;
        }

        private void HandleKeyword(Keyword keyword)
        {
            switch (keyword) //Check GetKeywordByString
            {
                case Keyword.Keyword_Category:
                {
                    //Here we handle the category keyword
                    string category = m_streamReader.ReadLine();
                    switch (category)
                    {
                        case "Rude":
                            m_currentCategory = VocabularyCategory.VocabularyCategory_Rude;
                            break;
                        case "Kind":
                            m_currentCategory = VocabularyCategory.VocabularyCategory_Kind;
                            break;
                        case "Awkward":
                            m_currentCategory = VocabularyCategory.VocabularyCategory_Awkward;
                            break;
                    }
                    break;
                }

                //You can add more here like this
                //case Keyword.SOME_KEYWORD_YOU_HAVE_DECLARED:
                //{
                //    //your logic if you've read that keyword
                //    break; //This says "handle only this word"
                //}

                case Keyword.Keyword_BeginWords:
                {
                    m_isReading = true;

                    break;
                }

                case Keyword.Keyword_EndWords:
                {
                    m_isReading = false;
                    break;
                }
            }
        }

        //Returns Keyword_NotAString if not found
        private Keyword GetKeywordByString(string line)
        {
            switch (line)
            {
                case "Category":
                    m_keyword = Keyword.Keyword_Category;
                    break;
                case "BeginWords":
                    m_keyword = Keyword.Keyword_BeginWords;
                    break;
                case "EndWords":
                    m_keyword = Keyword.Keyword_EndWords;
                    break;
            }
            return m_keyword;
        }

        private Dictionary<VocabularyCategory, List<string>> m_Vocabulary;
        private Dictionary<VocabularyCategory, int> m_categoryCurrentIndexes;
        private Dictionary<VocabularyCategory, int> m_categoryWordCounts;
        private VocabularyCategory m_currentCategory;
        private System.IO.StreamReader m_streamReader;
        private bool m_isReading;
        private bool m_isVocabularyInitialized;
        private bool m_hasCountedWords;
        private Keyword m_keyword;
        private Keyword m_lastKeyword;
    }
}
